local skynet = require "skynet"

-- Entity
local Entity = class("Entity")

-- self.recordset格式如下：
--[[
{
	[mid1] = { field1 = 1, field2 = 2 },
	[mid2] = { field1 = 1, field2 = 2 }
}
--]]


function Entity:ctor()
	self.recordset = {}			-- 存放记录集
	--setmetatable(self.recordset, { __mode = "k" })
	self.tbname = ""			-- 表名
	--self.sql = ""				-- sql语句
	--self.tbschema = {}		-- 表结构
	self.pk = ""				-- 主键字段
	self.key = ""				-- key
	self.indexkey = ""			-- indexkey
	self.type = 0				-- 表类型：1、config，2、user，3、common
	self.operate = nil --操作db的对象
end

-- 获取redis下一个编号
function Entity:getNextId()
	return send_redis({ "incr", self.tbname .. ":" .. self.pk })
end

function Entity:init(pk, key, indexkey)
	self.pk, self.key, self.indexkey = pk,key,indexkey
end


-- 加载表数据
function Entity:load()
	local record = self.operate:get(self.tbname)
	local key
	for k,v in pairs(record) do
		key = v[self.key]
		self.recordset[key] = v
	end		
	-- print(self.recordset,"_______self.recordset")
	return self.recordset		
end

-- 再从redis加载到内存
function Entity:reload(mid)
	if self.recordset[mid] then
		self.recordset[mid] = nil
	end
	return self:get(mid)
end

-- 卸载玩家数据
function Entity:unload(mid)
	local rs = self.recordset[mid]
	if rs then
		self.operate:unload(self,rs)		
		for k, v in pairs(rs) do
			rs[k] = nil
		end
		self.recordset[mid] = nil
		-- redis是否需要移除待定
		-- 从redis删除，但不删除mysql中的数据
	end
end

-- record为k,v形式table
-- 内存中不存在，则添加，并同步到redis
function Entity:add(record, nosync)
	local id = record[self.key] --
	if not id then
		return 
	end
	-- 记录已经存在，返回
    if self.recordset[id] then
    	return ret, self.recordset[id]
    end 
	local ret = self.operate:add(self,record, nosync)
	if ret then
		--self.recordset[id] = record
	end
	return ret, record
end

-- record中包含mid字段,record为k,v形式table
-- 从内存中删除，并同步到redis
function Entity:delete(record, nosync)

	local id = record[self.key] 
 --    if not id or not self.recordset[id] then
 --    	return 
 --    end 	
	
	local ret = self.operate:delete(self,record, nosync)
	if ret then 
		self.recordset[id] = nil
	end
	return ret
end

-- record中包含mid字段,record为k,v形式table
-- 仅从内存中移除，但不同步到redis
function Entity:remove(record)
	local id = record[self.key] 
    if not id or not self.recordset[id] then
    	return 
    end 
    self.recordset[id] = nil
	return true
end

-- record中包含mid字段,record为k,v形式table
function Entity:update(record, nosync)
	local id = record[self.key] 
    if not id or not self.recordset[id] then
    	return 
    end 
	-- print("_____1111111_______record__",id,record,self.recordset[id])
	local ret = self.operate:update(self,record, nosync)
	if ret then
		-- print("____________record__",record,self.recordset[id])
		for k, v in pairs(record) do
			-- print("___k,v",k,v)
			self.recordset[id][k] = v
		end
	end
	return ret
end

-- 从内存中获取，如果不存在，说明是其他的离线玩家数据，则加载数据到redis
-- field为空，获取整行记录，返回k,v形式table
-- field为字符串表示获取单个字段的值，如果字段不存在，返回nil
-- field为一个数组形式table，表示获取数组中指定的字段的值，返回k,v形式table
function Entity:get(mid, field)
	if not mid then 
		print("________________Entity:get__mid is null")
		return
	end
	-- 内存中存在
	local record
	if self.recordset[mid] then
		if not field then
			record = self.recordset[mid]
		elseif type(field) == "string" then
			record = self.recordset[mid][field]
		elseif type(field) == "table" then
			record = {}
			for i=1, #field do
				local t = self.recordset[mid]
				record[field[i]] = t[field[i]]
			end
		end
		-- print("________111111111____record__",record)
		return record
	end

	-- 从redis获取，如果redis不存在，从mysql加载
	local orifield = field
	if type(field) == "string" then
		field = { field }
	end
	--record = skynet.call("dbmgr", "lua", "get_user_single", self.tbname, mid,field) --不存在返回空的table {}
	record = self.operate:get(self.tbname,mid,field)
	if not table.empty(record) then
		self.recordset[mid] = record
		if type(orifield) == "string" then
			return record[orifield]
		end
	end

	if table.empty(record) and type(orifield) == "string" then return end

	return record
end

--只从内存中取玩家数据
function Entity:getFromMem(mid, field)
	-- 内存中不存在，说明玩家没有登录
	local record
	if self.recordset[mid] then
		if not field then
			record = self.recordset[mid]
		elseif type(field) == "string" then
			record = self.recordset[mid][field]
		elseif type(field) == "table" then
			record = {}
			for i=1, #field do
				local t = self.recordset[mid]
				record[field[i]] = t[field[i]]
			end
		end
		return record
	end
	return nil
end

-- field为字符串表示获取单个字段的值
-- field为一个数组形式table，表示获取数组中指定的字段的值，返回k,v形式table
function Entity:getValue(mid, field)
	if not field then return end
	local record = self:get(mid, field)
	if record then
		return record
	end
end

-- 成功返回true，失败返回false或nil
-- 设置单个字段的值，field为字符串，value为值
-- 设置多个字段的值，field为k,v形式table，value为空
function Entity:setValue(mid, field, value)
	local record = {}
	record["mid"] = mid
	if value then
		record[field] = value
	else
		for k, v in pairs(field) do
			record[k] = v
		end
	end

	return self:update(record)
end

return Entity
